(function () {
    "use strict";

    // 定义全局 console 兼容 IE
    if (!window.console) {
        window.console = {};
    }
    // 集合了各种浏览器中的 console 方法
    var m = [
        "log", "info", "warn", "error", "debug", "trace", "dir", "group",
        "groupCollapsed", "groupEnd", "time", "timeEnd", "profile", "profileEnd",
        "dirxml", "assert", "count", "markTimeline", "timeStamp", "clear"
    ];
    // 根据 console 是否缺少某个方法来定义，一个也不落下
    for (var i = 0; i < m.length; i++) {
        if (!window.console[m[i]]) {
            window.console[m[i]] = function () {
            };
        }
    }

    // 定义全局变量默认值
    window.YII_DEBUG = window.YII_DEBUG || false;
    window.UID = window.UID ? UID : 0;

    // YII_DEBUG 常量将开启 js debug 模式
    if (window.YII_DEBUG) {
        console.log('Js debug on');
    }
})();


(function ($) {
    "use strict";

    /**
     * 通用ajax表单配置
     *
     * @param $form
     * @param $submitBtn
     * @param callbacks
     * @param defaultAction
     * @returns {{type: string, dataType: string, beforeSubmit: Function, success: Function, error: Function}}
     */
    function getCommonFormSettings($form, $submitBtn, callbacks, defaultAction) {
        return {
            type: 'POST',
            dataType: 'json',
            beforeSubmit: function (inputs) {
                if (YII_DEBUG) console.group('Ajaxform');
                if (YII_DEBUG) console.log('Inputs: ', inputs);

                if (callbacks.beforeSubmit && $.isFunction(callbacks.beforeSubmit)) {
                    var ret = callbacks.beforeSubmit.call($form, inputs);
                    if (typeof ret !== 'undefined' && !ret) {
                        if (YII_DEBUG) console.groupEnd('Ajaxform');
                        return false;
                    }
                }

                // 检查可否提交
                if (!$submitBtn.xyIsEnable()) {
                    if (YII_DEBUG) console.groupEnd('Ajaxform');
                    return false;
                }
                // 开始提交前禁用提交
                $submitBtn.data('text', $submitBtn.text()).text('提交中...').xyDisable();

                return true;
            },
            success: function (e) {
                if (YII_DEBUG) console.log('Form submit success and return :', e);
                if (YII_DEBUG) console.groupEnd('Ajaxform');

                // 清空每个输入项的错误提示
                $form.find("input[type!=hidden]").each(function () {
                    var $input = $(this);
                    $input.inputErrorRemove($input.parent().parent());
                });

                // 提交有返回后允许再次提交
                $submitBtn.text($submitBtn.data('text')).xyEnable();

                if (e.data.hasOwnProperty('forceRefresh')) {
                    location.reload();
                }

                if (e.result !== 0) {
                    if (defaultAction) {
                        // 为每个有错误信息的输入项加上错误提示
                        if (e.data.hasOwnProperty('validation')) {
                            for (var name in e.data.validation) {
                                var message = e.data.validation[name],
                                    $input = $form.find(":input[name='" + name + "']");
                                $input.inputError(message, $input.parents('.inp'));
                            }
                        }
                        if (e.message.length > 0) {
                            $submitBtn.xyBtnTip(e.message);
                        }
                    }
                    if (callbacks.error && $.isFunction(callbacks.error)) {
                        callbacks.error.call($form, e);
                    }

                } else {
                    if (callbacks.success && $.isFunction(callbacks.success)) {
                        callbacks.success.call($form, e);
                    }
                    if (defaultAction) {
                        if (e.data.hasOwnProperty('redirect')) {
                            //window.location.href = e.data.redirect;
                            top.location.href = e.data.redirect;
                        } else if (e.data.hasOwnProperty('refresh')) {
                            location.reload();
                        } else if (e.message.length > 0) {
                            $submitBtn.xyBtnTip(e.message, true);
                        }
                    }
                }
            },
            error: function (e) {
                if (YII_DEBUG) console.log('Form submit failed with Exception !');
                if (YII_DEBUG) console.groupEnd('Ajaxform');
                var data = e.responseJSON;

                if (!data) {
                    throw new Error('Response is not JSON !');
                }

                if (data.data && data.data.hasOwnProperty('forceRefresh')) {
                    location.reload();
                }

                if (defaultAction) {
                    if (data.data.hasOwnProperty('redirect')) {
                        window.location.href = data.data.redirect;
                    } else if (data.data.hasOwnProperty('refresh')) {
                        location.reload();
                    } else if (data.message.length > 0) {
                        alert(data.message);
                    }
                }

                if (callbacks.systemError && $.isFunction(callbacks.systemError)) {
                    callbacks.systemError.call($form, e);
                }
            }
        };
    }

    /**
     * 将一个表单直接以通用ajax表单的形式提交
     *
     * @param settings
     * @param callbacks
     * @param defaultAction
     */
    $.fn.submitCommonForm = function (settings, callbacks, defaultAction) {
        defaultAction = defaultAction !== false;
        callbacks = callbacks || {};
        callbacks = $.extend({
            success: false,
            error: false,
            beforeSubmit: false,
            systemError: false
        }, callbacks);

        var $form = $(this),
            $button = $form.find('.btn-submit'),
            defaultSettings = getCommonFormSettings($form, $button, callbacks, defaultAction);

        settings = $.extend(settings, defaultSettings);
        if (YII_DEBUG) console.log('Ajaxform settings :', settings);

        $form.ajaxSubmit(settings);
    };

    /**
     * 将一个表单绑定为通用ajax表单
     *
     * @param settings
     * @param callbacks
     * @param defaultAction
     */
    $.fn.bindCommonForm = function (settings, callbacks, defaultAction) {
        defaultAction = defaultAction !== false;
        callbacks = callbacks || {};
        callbacks = $.extend({
            success: false,
            error: false,
            beforeSubmit: false,
            systemError: false
        }, callbacks);

        var $form = $(this),
            $button = $form.find('.btn-submit'),
            defaultSettings = getCommonFormSettings($form, $button, callbacks, defaultAction);

        settings = $.extend(settings, defaultSettings);
        if (YII_DEBUG) console.log('Ajaxform settings :', settings);

        $form.ajaxForm(settings);
        $button.on('click.submit', function (e) {
            if (YII_DEBUG) console.log('Ajaxform settings :', settings);
            $form.submit();
            e.preventDefault();
            //return false;
        });
    };

    $.fn.ajaxBasicUpload = function (filetype, limiSize, inputName, callback) {
        $(this).fileupload({
            url: '/upload/' + filetype + '?size=' + limiSize,
            dataType: 'json',
            done: function (e, data) {
                var $this = $(this),
                    $input = $this.next('input'),
                    result = data.result;

                // 上传成功
                if (result.result === 0) {
                    if ($input.length <= 0) {
                        $input = $('<input type="hidden" name="' + inputName + '" value="" >');
                        $this.after($input);
                    }

                    $input.val(result.data.filepath);
                }

                callback(result);
            }
        }).prop('disabled', !$.support.fileInput);
    };

    $.fn.xyRefreshForm = function () {
        var $form = $(this);
        $form.clearForm();
    };

    $.fn.ajaxFieldCheck = function (url, callback) {
        var $input = $(this);
        $input.blur(function () {
            var key = $input.attr('name'),
                value = $input.val();
            $.get(url, key + '=' + value, function (e) {
                /**
                 * function callback(success, message, data)
                 */
                callback.call($input.get(0), e.result === 0, e.message, e.data);
            }, 'json');
        });
    };

    //$.fn.inputError = function (message) {
    //    var $input = $(this),
    //        name = $input.attr('name'),
    //    // 你可以事先放置好 <span class="txt-err error-{input的name}"></span> 标签来定义错误提示的位置
    //        $errorBox = $input.siblings('.error-' + name);
    //
    //    $input.addClass('inptxt-err');
    //    if ($errorBox.length > 0) {
    //        $errorBox.html('<i class="i-err"></i>' + message).show();
    //    } else {
    //        $input.parent().append('<span class="txt-err error-' + name + '"><i class="i-err"></i>' + message + '</span>');
    //    }
    //};

    $.fn.inputError = function (message, target) {
        var $input = $(this),
            name = $input.attr('name'),
            target = target && target.length > 0 ? target : $input.parent(),
        // 你可以事先放置好 <span class="txt-err error-{input的name}"></span> 标签来定义错误提示的位置
            $errorBox = target.find('.error-' + name);

        if ($errorBox.length > 0) {
            $errorBox.html(message).show();
        } else {
            target.append('<span class="err error-' + name + '">' + message + '</span>');
        }
    };

    $.fn.inputErrorRemove = function (target) {
        var $input = $(this),
            target = target && target.length > 0 ? target : $input.parent(),
            $errorBox = target.find('.error-' + $input.attr('name'));

        if ($errorBox.length > 0) {
            $errorBox.hide();
        }
    };

    $.fn.requestMobileVerify = function ($input, successCallback, failCallback) {
        var $button = $(this);

        $button.click(function () {
            if (!$button.xyIsEnable()) {
                return false;
            }
            var mobile, checkUnique;
            if ($input === 'default') {
                mobile = 'default';
                checkUnique = 0;
            } else {
                mobile = $input.val();
                checkUnique = $input.attr('data-check');
            }
            // 临时加，以后优化
            var captcha =  $('input[name="mobile_captcha"]').val();

            $.get('/requestVerify/mobileVerify1', {
                mobile: mobile,
                check_unique: checkUnique,
                captcha: captcha || ''
            }, function (e) {
                if (!isAjaxSuccess(e)) {
                    if ($.isFunction(failCallback)) {
                        failCallback.call($button.get(0), e.message);
                    }
                } else {
                    if ($.isFunction(successCallback)) {
                        successCallback.call($button.get(0), e.message);
                    }
                }
            }, 'json');

            return false;
        });
    };

    $.fn.sendCode = function($form, success, fail)
    {
        var $button  = $(this),
            $mobile  = $form.find('input[name=mobile]'),
            $captcha = $form.find('input[name=captcha]'),
            $csrf    = $form.find('input[name=csrf]');
        $button.click(function () {
            if (!$button.xyIsEnable()) {
                return;
            }
            $.get('/requestVerify/codeverify', {
                mobile: $mobile.val(),
                captcha: $captcha.val()
            }, function(e) {
                if (!isAjaxSuccess(e))
                {
                    if ($.isFunction(fail)) {
                        fail.call($button.get(0), e.message, e.data);
                    }
                } else {
                    $csrf.val(e.data.token);
                    $.post('/requestVerify/code', {
                        item: e.data.item,
                        check: $button.data('check'),
                        scene: $button.data('scene'),
                        csrf : e.data.token
                    }, function(e) {
                        if (!isAjaxSuccess(e))
                        {
                            if ($.isFunction(fail)) {
                                fail.call($button.get(0), e.message, e.data);
                            }
                        } else {
                            if ($.isFunction(success)) {
                                success.call($button.get(0), e.message)
                            }
                        }
                    }, 'json');
                }
            }, 'json');
            return;
        });
    };

    $.fn.buttonCountDown = function () {
        var $button = $(this);

        // 倒计时60秒
        var i = 60,
            timer = setInterval(function () {
                if (i <= 0) {
                    clearInterval(timer);
                    $button.xyEnable().text('重新获取').data('ready', 1);
                    return false;
                }

                i--;
                $button.text('重新获取 (' + i + ')');
            }, 1000);

        $button.data('timer', timer);
        $button.xyDisable().text('重新获取 (' + i + ')').data('ready', 0);
    };

    /**
     * 停止数秒
     * message string为停止后 数秒按钮上的文字，默认为 '重新获取'四字
     */
    $.fn.buttonCountDownStop = function (message) {
        var $button = $(this),
            timer = $button.data('timer');

        clearInterval(timer);
        message = message || '重新获取';
        $button.xyEnable().text(message).data('ready', 1);
    };

    $.fn.loadImgVerifyCode = function () {
        var $img = $(this);

        $img.click(function () {
            var timestamp = new Date().getTime();
            $img.attr('src', '/requestVerify/imgVerify?v=' + timestamp);
        });
        $img.trigger('click');
    };

    $.fn.xyEnable = function (name) {
        name = name ? '_' + name : '';
        var $button = $(this);
        if ($button.hasClass('btn-disable')) {
            $button.removeClass('btn-disable');
        }
        $button.data('xyEnable' + name, 0); // 因为默认值是 null ，所以enable以 0 为启用状态
        return $button;
    };

    $.fn.xyDisable = function (name) {
        name = name ? '_' + name : '';
        var $button = $(this);
        if ($button.hasClass('btn')) {
            $button.addClass('btn-disable');
        }
        $button.data('xyEnable' + name, 1);
        return $button;
    };

    $.fn.xyIsEnable = function (name) {
        name = name ? '_' + name : '';
        return !$(this).data('xyEnable' + name) && 1;
    };

    /**
     * radio组件，结合迅雷特定的radio元素使用
     *
     * 比如下面这种结构， radio_sel 表示选中， data-v 用来存放radio的值
     * <a href="#" class="xy-radio pay_way b_alipay">
     *     <span class="radio radio_sel" data-v="ALIPAY"></span>支付宝
     * </a>
     *
     * @param {jQuery} $form
     * @param {string} name
     */
    $.fn.xyRadio = function ($form, name) {
        var $input = $form.find('input[name=' + name + ']'),
            $btns = $(this),
            $default = $btns.find('.radio_sel');

        // 检查参数
        if ($form.length <= 0) {
            throw new Exception('没有指定radio所属form');
        }
        if (name.length <= 0) {
            throw new Exception('没有指定radio在POST、GET中所用字段名');
        }

        // 生成隐藏input域，这样无论ajax还是普通提交都能有值
        if ($input.length <= 0) {
            $input = $('<input type="hidden" name="' + name + '">');
            $form.prepend($input);
        }

        // 如果有默认值则使用默认值
        if ($default.length > 0) {
            $input.val($default.last().attr('data-v'));
        }

        // 绑定事件
        $btns.click(function () {
            $btns.find('.radio_sel').removeClass('radio_sel');

            var $radio = $(this).find('.radio');

            $radio.addClass('radio_sel');
            $input.val($radio.attr('data-v'));
        });
    };

    /***
     * 自定义checkbox
     * $(element).xyCheckbox(selectCallback, notSelectCallback);
     * selectCallback 为选中时候出发的回调函数
     * notSelectCallback为去除选中时候的回调函数
     */
    $.fn.xyCheckbox = function (selectCallback, notSelectCallback) {
        if ($(this).hasClass('checked')) {
            $(this).removeClass('checked');
            if ($.isFunction(notSelectCallback)) {
                notSelectCallback.call($(this));
            }
        } else {
            $(this).addClass('checked');
            if ($.isFunction(selectCallback)) {
                selectCallback.call($(this));
            }
        }
    }

    /**
     * 弹窗显示
     */
    $.fn.xyPopShow = function (noMask, callbacks) {
        var $this = $(this),
            $mask = $("#popMask");

        callbacks = callbacks || {};
        noMask = noMask === true;

        $this.data('xy-no-mask', noMask);

        if ($this.length <= 0) {
            throw new Error('弹窗DOM不存在');
        }
        if ($mask.length <= 0) {
            throw new Error('遮罩DOM不存在');
        }

        if (callbacks.afterHide) {
            $this.on('xy-afterHide', callbacks.afterHide);
        }

        $this.show();
        if (!noMask) {
            $mask.show();
        }
    };

    /**
     * 弹窗隐藏
     */
    $.fn.xyPopHide = function () {
        var $this = $(this),
            $mask = $("#popMask"),
            noMask = $this.data('xy-no-mask');

        if ($this.length <= 0) {
            throw new Exception('弹窗DOM不存在');
        }
        if ($mask.length <= 0) {
            throw new Exception('遮罩DOM不存在');
        }

        $this.hide();
        $this.trigger('xy-afterHide');
        if (!noMask) {
            $mask.hide();
        }
    };

    $.fn.xyLogin    = function () {
        if ($("#loginframe").length == 0) {
            var html = '<div id="loginframe" style="position:fixed; _position:absolute; left:50%; top:50%; margin:-210px 0 0 -170px; background:#fff; z-index:10000; box-shadow:0 0 20px rgba(0,0,0,.4); display:none;"> </div>';
            $('body').append(html);
            xyLogin.init({
                debug: true,
                src: "/user/login",
                container: 'loginframe',
                afterLogin: function(redirect) {
                    window.location.href = redirect;
                }
            });
        }
        this.click(function() {
            $("#loginframe").xyPopShow();
        });
    },

    /***
     *绑定确定和取消按钮的点击函数，
     且this代表jquery(弹出框);
     **/
    $.fn.bindCallback = function (yesCallback, noCallback) {
        var yesCallback = $.isFunction(yesCallback) ? yesCallback : this.xyPopHide;
        var noCallback = $.isFunction(noCallback) ? noCallback : this.xyPopHide;
        var $this = this;
        this.find('.btn-confirm').unbind('click').click(function () {
            yesCallback.call($this);
        });
        this.find('.btn-cancel').unbind('click').click(function () {
            noCallback.call($this);
        });
    };

    $.xyConfirm = function (msg, yesCallback, noCallback) {
        if ($("#xyConfirmPop").length == 0) {
            // 初次加载生成渲染方法
            var html = '<div class="u-pop2" id="xyConfirmPop">\
                        <div class="pop_cont">\
                            <p class="warn2"><i class="ico_warn2"></i><span class="warn2_txt"></span></p>\
                            <div class="btn_box">\
								<span class="tips_suc" style="display:none;"><i class="ico_ok"></i>提交成功</span>\
								<span class="tips_fail" style="display:none;"><i class="ico_err"></i>提交失败</span>\
                                <a href="javascript:;" class="u-btn2-sml btn-confirm">确定</a>\
                                <a href="javascript:;" class="u-btn2-sml btn-cancel">取消</a>\
                            </div>\
                        </div>\
                    </div>';
            $('body').append($(html));
        }
        var $confirm = $("#xyConfirmPop");
        $confirm.bindCallback(yesCallback, noCallback);
        $confirm.find('span').text(msg).end().xyPopShow();
    };

    /***
     * 需要短信验证
     */
    $.fn.xyCheckSms = function (yesCallback) {
        var $this = this;
        $this.on('click', '.btn-verify', function () {
            var $verifyBtn = $(this);
            if (!$verifyBtn.xyIsEnable()) {
                return false;
            }
            $.getJSON('/console/user/sendCheckSms').done(function (result) {
                if (result.result == 0) {
                    $verifyBtn.xyDisable();
                    $verifyBtn.buttonCountDown();
                } else {
                    $this.find('.tips_fail').html('<i class="ico_err"></i>' + result.message).show(0).delay(3000).hide(0);
                }
            });
        });

        $this.bindCallback(
            function () {
                $this = this;
                if ($("#smsPopVerify").val() == '') {
                    $("#smsPop").find('.tips_fail').html('<i class="ico_err"></i>请输入验证码').show(0).delay(3000).hide(0);
                    return false;
                }
                $.getJSON('/console/user/checkSms', {code: $("#smsPopVerify").val()}).done(function (result) {
                    if (result.result == 0) {
                        $this.find('.btn-confirm').xyEnable();
                        $this.find('.btn-verify').buttonCountDownStop('获取验证码');
                        yesCallback.call($this);
                    } else {
                        $this.find('.tips_suc').hide();
                        $this.find('.tips_fail').html('<i class="ico_err"></i>' + result.message).show(0).delay(3000).hide(0);
                    }
                });
            },
            function () {
                $this.find('.btn-confirm').xyEnable();
                $this.find('.btn-verify').buttonCountDownStop('获取验证码');
            }
        );
    };

    /**
     * 生成分页组件
     *
     * @param {number} currentPage 当前页
     * @param {number} perpage 每页多少行
     * @param {number} total 总共多少行
     * @param {function} callback 点击按钮的回调，默认传递页数作为参数
     * @returns {boolean}
     */
    $.fn.genPager = function (currentPage, perpage, total, callback) {
        var $pager = $(this);
        if (total <= perpage) {
            $pager.empty();
            return false;
        }

        var start, end,
            maxVisibleSize = 10,
            pages = [],
            currentPage = parseInt(currentPage),
            maxPage = Math.ceil(total / perpage);

        // 根据 maxVisibleSize 只生成指定页数的按钮以供显示
        if (maxPage > maxVisibleSize) {
            if (currentPage - Math.floor(maxVisibleSize / 2) <= 0) {
                start = 1;
                end = 10;
            } else if (currentPage + Math.ceil(maxVisibleSize / 2) >= maxPage) {
                start = maxPage - 10;
                end = maxPage;
            } else {
                start = currentPage - Math.floor(maxVisibleSize / 2) + 1;
                end = currentPage + Math.ceil(maxVisibleSize / 2);
            }
        } else {
            start = 1;
            end = maxPage;
        }
        if (start != 1) {
            pages.push({page: start - 1, name: '...'});
        }
        for (var i = start; i <= end; i++) {
            pages.push({page: i, name: i});
        }
        if (end != maxPage) {
            pages.push({page: end + 1, name: '...'});
        }

        var source, render, html;

        // 根据参数渲染分页html
        if (!$pager.data('loaded')) {
            // 初次加载生成渲染方法
            source = '<p class="total_page">共<span>{{total}}</span>条，每页显示{{perpage}}条</p> \
                        <div class="page_box"> \
                            {{if currentPage <= 1}} \
                            <a class="page_prev off" href="#">&lt;</a> \
                            {{else}} \
                            <a class="page_prev" href="#{{currentPage-1}}">&lt;</a> \
                            {{/if}} \
                            \
                            <span class="page_wp"> \
                            {{each pages as v}} \
                                {{if v.page == currentPage}} \
                                <a class="on" href="#">{{v.name}}</a> \
                                {{else}} \
                                <a href="#{{v.page}}">{{v.name}}</a> \
                                {{/if}}\
                            {{/each}} \
                            </span> \
                            \
                            {{if currentPage >= maxPage}} \
                            <a class="page_next off" href="#">&gt;</a> \
                            {{else}} \
                            <a class="page_next" href="#{{currentPage+1}}">&gt;</a>\
                            {{/if}} \
                        </div>';
            render = template.compile(source);
            $pager.data('render', render);
        } else {
            render = $pager.data('render');
        }

        html = render({
            'currentPage': parseInt(currentPage),
            'perpage': perpage,
            'total': total,
            'maxPage': maxPage,
            'pages': pages
        });
        $pager.html(html);

        // 绑定点击事件
        if (!$pager.data('loaded')) {
            // 初次加载绑定事件
            $pager.on('click', 'a', function () {
                var page = $(this).attr('href');
                if (page === '#') {
                    return false;
                } else {
                    page = page.substr(1);
                }

                callback(page);
            });
            $pager.data('loaded', 1);
        }
    };

    /**
     * 新版分页组件
     * @param {number} currentPage 当前页
     * @param {number} perpage 每页多少行
     * @param {number} total 总共多少行
     * @param {function} callback 点击按钮的回调，默认传递页数作为参数
     * @param {bool} isHideTip 是否隐藏页面前面那行共多少，当前多少
     * @returns {boolean}
     */
    $.fn.genPagerNew = function (currentPage, perpage, total, callback, isHideTip) {
        var $pager = $(this);
        if (total <= perpage) {
            $pager.empty();
            return false;
        }

        var start, end,
            maxVisibleSize = 10,
            pages = [],
            currentPage = parseInt(currentPage),
            maxPage = Math.ceil(total / perpage);

        // 根据 maxVisibleSize 只生成指定页数的按钮以供显示
        if (maxPage > maxVisibleSize) {
            if (currentPage - Math.floor(maxVisibleSize / 2) <= 0) {
                start = 1;
                end = 10;
            } else if (currentPage + Math.ceil(maxVisibleSize / 2) >= maxPage) {
                start = maxPage - 10;
                end = maxPage;
            } else {
                start = currentPage - Math.floor(maxVisibleSize / 2) + 1;
                end = currentPage + Math.ceil(maxVisibleSize / 2);
            }
        } else {
            start = 1;
            end = maxPage;
        }
        if (start != 1) {
            pages.push({page: start - 1, name: '...'});
        }
        for (var i = start; i <= end; i++) {
            pages.push({page: i, name: i});
        }
        if (end != maxPage) {
            pages.push({page: end + 1, name: '...'});
        }

        var source, render, html;

        // 根据参数渲染分页html
        if (!$pager.data('loaded')) {
            // 初次加载生成渲染方法
            source = '{{if isHideTip == false}} \
                        <span class="page-text">{{total}}条，共{{maxPage}}页</span> \
                     {{/if}} \
                        <ul> \
                            {{if currentPage <= 1}} \
                                <li><a class="btn-pre btn-pagedefault" href="#"></a></li> \
                            {{else}} \
                                <li><a class="btn-pre" href="#{{currentPage-1}}"></a></li> \
                            {{/if}} \
                            \
                            {{each pages as v}} \
                                {{if v.page == currentPage}} \
                                <li><a class="on" href="#">{{v.name}}</a></li> \
                                {{else}} \
                                <li><a href="#{{v.page}}">{{v.name}}</a></li> \
                                {{/if}}\
                            {{/each}} \
                            \
                            {{if currentPage >= maxPage}} \
                                <li><a class="btn-next btn-pagedefault" href="#"></a></li> \
                            {{else}} \
                                <li><a class="btn-next" href="#{{currentPage+1}}"></a></li> \
                            {{/if}} \
                        </ul>';
            render = template.compile(source);
            $pager.data('render', render);
        } else {
            render = $pager.data('render');
        }

        html = render({
            'currentPage': parseInt(currentPage),
            'perpage': perpage,
            'total': total,
            'maxPage': maxPage,
            'pages': pages,
            'isHideTip' :  isHideTip || false
        });
        $pager.html(html);

        // 绑定点击事件
        if (!$pager.data('loaded')) {
            // 初次加载绑定事件
            $pager.on('click', 'a', function () {
                var page = $(this).attr('href');
                if (page === '#') {
                    return false;
                } else {
                    page = page.substr(1);
                }

                callback(page);
            });
            $pager.data('loaded', 1);
        }
    };

    $.fn.xyTab = function () {
        var $container = $(this),
            $buttons = $container.find('.tab-button'),
            $tabs = $container.find('.tab-board');

        if ($container.length <= 0) {
            throw new Error('所选容器不存在！');
        }
        if ($buttons.length < 1) {
            throw new Error('所选容器中未检测到tab按钮！');
        }

        $buttons.click(function () {
            var $button = $(this),
                target = $button.attr('data-target'),
                $tab = $('#' + target);

            if ($tab.length < 1) {
                throw new Error('所点击按钮对应的tab无法获取！');
            }

            $tabs.hide();
            $tab.show();
            $button.parent().addClass('on').siblings().removeClass('on');
            return false;
        });

        // 根据 url#xxx 激活 #xxx 页
        var anchor = window.location.hash;
        if (anchor.length <= 0) {
            anchor = '#default';
        }
        $buttons.each(function (k, v) {
            var $v = $(v);
            if ($v.attr('href') === anchor) {
                $v.trigger('click');
                return false;
            }
        });
    };

    $.fn.xyBtnTip = function (msg, succeed, position) {
        var $tip,
            $btn = $(this);

        succeed = succeed || false;
        position = position || 'after';

        // 同一容器的情况下
        // 你可以事先放置好 <span class="tip"></span> 标签来定义 tip 的位置
        $tip = $btn.siblings('.tip');
        if ($tip.length <= 0) {
            $tip = $('<span class="tip" style="display: none;"></span>');
            if (position === 'before') {
                $btn.before($tip);
            } else {
                $btn.after($tip);
            }
        }

        if (succeed) {
            $tip.removeClass('registe-err').addClass('registe-ok');
        } else {
            $tip.removeClass('registe-ok').addClass('registe-err');
        }
        $tip.html(msg);

        $btn.trigger('xy-btntip-beforeshow', succeed);
        $tip.slideDown(function() {
            $btn.trigger('xy-btntip-show', succeed);
        });
        setTimeout(function () {
            $btn.trigger('xy-btntip-beforehide', succeed);
            $tip.slideUp('slow', function () {
                $btn.trigger('xy-btntip-hide', succeed);
            });
        }, 3000);
    };

    $.xyExchange = function (value, type) {
        var ret,
            rate = 0.18,
            value = parseFloat(value);

        if (value <= 0 || isNaN(value)) {
            return 0;
        }

        if (type === 'traffic') {
            ret = Math.floor(value * rate * 100) / 100;
        } else {
            ret = Math.floor(value / rate * 100) / 100;
        }

        return ret;
    };

    /**
     * 建议的后台轮询方法
     *
     * @param url
     * @param interval
     * @param callback
     */
    $.fn.xyGetPolling = function (url, interval, callback) {
        var $this = $(this),
            timer = setInterval(function () {
                // 通过动态改变 xy-polling 的值可以更新轮询状态
                var param = $this.data('xy-polling');
                $.get(url, param, function (e) {
                    callback(e, timer);
                }, 'json');
            }, interval);
    };

    /**
     * 在指定DOM内插入一个下拉框
     *
     * @param name
     * @param value
     * @param options
     */
    $.fn.xyDropdownSelect = function (name, value, options) {
        var html = '<span class="droptext">无</span> \
                    <a class="btn-dropbox" href="#"><i class="i-sj"></i></a> \
                    <input type="hidden" name="' + name + '" id="' + name + '"/> \
                    <ul class="dropbox-list"></ul>';
        var $this = this;
        $this.append(html).addClass('dropbox');
        var $droptext = $this.find('.droptext'),
            $input = $this.find('input'),
            $dropList = $this.find('.dropbox-list');

        for (var key in options) {
            if (options.hasOwnProperty(key)) {
                if (key == value) {
                    $droptext.text(options[key]);
                    $input.val(key);
                }

                $dropList.append('<li data-value="' + key + '"><a href="javascript:;">' + options[key] + '</a></li>');
            }
        }


        $this.on('click', '.droptext, .btn-dropbox', function() {
            $this.toggleClass('on');
            return false;
        });

        $(document).on('click', function() {
            $this.removeClass('on');
        });

        $dropList.on('click', 'li', function() {
            var $li = $(this),
                value = $li.attr('data-value'),
                text = $li.text();

            $droptext.text(text);
            $input.val(value);
            $input.change();
            $this.removeClass('on');
        });
    };

    //$.unreadMessageNum = function () {
    //    $.getJSON('/message/unread')
    //        .done(function (e) {
    //            if (isAjaxSuccess(e)) {
    //                if (e.data.unread_num > 0) {
    //                    $('#message-unread').text(e.data.unread_num).show();
    //                } else {
    //                    $('#message-unread').text('').hide();
    //                }
    //            }
    //        });
    //};
}(jQuery));

(function ($) {
    /***xySelect插件，模拟js select
     * 可以params中传入url 或者list。
     * 如果传入url，则请求url并展示结果
     */
    $.fn.xySelect = function (params) {
        params = $.extend({}, {url: '', list: [], defaultKey: '', isInit: 0}, params);
        var $this = this;
        if (!$this.data('selectEventBind')) {
            $this.on('click', 'input, .btn-drop', function () {
                $this.find('.drop-list').toggle();
            });

            $this.on('click', 'ul.drop-list a', function () {
                var selectValue = $(this).text();
                var selectKey = $(this).data('key');
                $this.find('.drop-list').hide();
                $this.find('input:text').val(selectValue);
                $this.find('input:hidden').val(selectKey);
                if (!params.isInit) {
                    $this.find('input:hidden').trigger('change');
                } else {
                    /**第一次不触发change，其他触发**/
                    params.isInit = 0;
                }
            });
        }

        if (params.url != '') {
            $.getJSON(params.url).done(function (result) {
                if (result && result.result == 0) {
                    xySelectFill.call($this, result.data);
                }
            });
        } else if (params.list) {
            xySelectFill.call($this, params.list, params.defaultKey);
        }
    }

    function xySelectFill(list, defaultKey) {
        var i = 0,
            html = '';
        for (var key in list) {
            html += '<li ' + (i == 0 ? 'class="nobdr"' : '') + '><a href="javascript:;" data-key="' + key + '">' + list[key] + '</a></li>';
            i++;
        }
        this.find('ul.drop-list').empty().html(html);
        if (defaultKey) {
            this.find('ul.drop-list a[data-key=' + defaultKey + ']').trigger('click');
        } else {
            this.find('ul.drop-list li').eq(0).find('a').trigger('click');
        }
    };
})(jQuery);

// 页面初始化完成后需要全局执行的代码
$(function () {
    "use strict";

    // input输入框加入聚焦效果
    var $inputs = $('input.inptxt');
    if ($inputs.length > 0) {
        $inputs.focus(function () {
            $(this).addClass('inptxt-focus');
        });

        $inputs.blur(function () {
            $(this).removeClass('inptxt-focus');
        });
    }


    // 全局快捷键绑定
    key.filter = function (event) {
        var tagName = (event.target || event.srcElement).tagName;
        // 这是文档中给出的一种根据当前 tag 动态改变 scope 的方法，可以继续扩展
        // textarea 区域中不可触发默认的 enter 快捷键

        key.setScope(/^TEXTAREA$/.test(tagName) ? 'no_enter' : 'ok_enter');
        return true;
    };
    // Enter 键
    /*key('enter', 'ok_enter', function () {
        $('form:visible').submit();
    });*/
    key('esc', function () {
        $('.xy-pop:visible').each(function () {
            $(this).xyPopHide();
        });
    });

    // 全局绑定弹出框 X 按钮关闭事件
    $(document).on('click', '.close, .btn-cancel, .btn-close', function () {
        var $pop = $(this).parents('.xy-pop');
        if ($pop.length > 0) {
            $pop.xyPopHide();
        }

        return false;
    });

    // 全局绑定点击下拉框事件
    $(document).on('click', '.dropdown', function () {
        var target = $(this).attr('data-target'),
            $target = $('#' + target);
        if ($target.length > 0) {
            $target.slideToggle();
        }

        return false;
    });

    // 全局绑定悬浮下拉事件
    $(document).on('mouseenter', '.xy-dropdown', function () {
        console.log('enter');
        var $target = $('#' + $(this).attr('data-target'));
        if ($target.length > 0) {
            $target.show();
        }

        return false;
    });
    $(document).on('mouseleave', '.xy-dropdown', function () {
        console.log('leave');
        var $target = $('#' + $(this).attr('data-target'));
        if ($target.length > 0) {
            $target.hide();
        }

        return false;
    });

    // 登录后才执行
    /*
    if (UID > 0) {
        // 全局获取未读消息数
        $.unreadMessageNum();

        // 全局新建工单弹窗事件
        $('.btn-new-ticket').click(function () {
            $('#new-ticket').xyPopShow();
        });

        // 全局获取未读工单数
        $.get('/ticket/countNewReply', '', function (e) {
            if (isAjaxSuccess(e)) {
                if (e.data.newReply > 0) {
                    if (e.data.newReply < 10) {
                        var text = '&nbsp;1&nbsp;';
                    }
                    $('#ticket-new-reply').html(text).show();
                }
            }
        }, 'json');


        // 全局新建工单弹窗表单
        var $ticketForm = $('#ticket-form');
        $ticketForm.bindCommonForm({
            url: '/ticket/new'
        }, {
            success: function (e) {
                $(this).xyRefreshForm();
                $(this).find('.btn-preview').remove(); // 删除缩略图
            }
        });
        $ticketForm.find('#ticket-fileupload').fileupload({
            url: '/upload/img?size=5242880',
            dataType: 'json',
            dropZone: $ticketForm,
            add: function (e, data) {
                // 检测已上传图片数
                if ($ticketForm.find('.btn-preview').length >= 6) {
                    $ticketForm.find('.btn-submit').xyBtnTip('最多只能上传6张图片');
                } else {
                    data.submit();
                }
            },
            done: function (e, data) {
                var $this = $(this),
                    result = data.result;

                // 上传成功
                if (result.result === 0) {
                    $('.upload-list').append(' \
                        <a class="attach_box btn-preview" href="javascript:;"> \
                            <img src="' + result.data.path + '"> \
                            <i class="btn-file-del btn-delete"></i> \
                            <input type="hidden" name="attachments[]" value="' + result.data.filepath + '" > \
                        </a>');
                } else {
                    $ticketForm.find('.btn-submit').xyBtnTip(result.message);
                }
            }
        }).prop('disabled', !$.support.fileInput);
        // 删除上传图片
        $ticketForm.on('click', '.btn-delete', function () {
            $(this).parents('a').remove();
        });
        $ticketForm.on('click', '.btn-preview>img', function () {
            var $pop = $('#preview-ticket'),
                src = $(this).attr('src');

            $pop.find('img').attr('src', src);
            $pop.xyPopShow(true);
        });
    }
    */
});

function isAjaxSuccess(e) {
    if (typeof e === 'string') {
        throw new Error('参数错误，不能为字符串，必须是个对象');
    }
    return e.result === 0;
}




// 表单类组件集合
var xyForm = {};

/*
 * 下拉列表组件
 * data参数格式为：
    {
        name: 'domain_name',
        value: 'all',
        emptyTitle: '域名列表为空',      // options为空是显示的title
        emptyTip: '域名列表为空',        // options为空时列表显示的内容，需与emptyTitle一起用，否则title没内容显示
        options: {
            "all": "全部域名",           // key为all的值，会显示在第一个
            "sy.com": "sy.com",
            "syy.com": "syy.com",
            "test.com": "test.com",
            "tes1t.com": "tes1t.com"
        }
    }
 * option参数：
    {
        mid: true/false,    // 稍窄的宽度
        width: 120          // 指定具体宽度
    }
 */
xyForm.DropdownSelect = Component.extend({
    hooks: {
        dropbox: '.dropbox'
    },
    events: {
        'li:click': 'optionClick'
    },
    construct: function(data, option){
        var that = this;
        $(document).click(function(){
            that.$dropbox.removeClass('on');
        });
        this.$root.click(function(e){
            that.$dropbox.toggleClass('on');
            that.publish('hideDroplist', that);
            e.preventDefault();
            e.stopPropagation();
        });
        this.subscribe('hideDroplist', function(instance){
            if(instance !== that){
                that.$dropbox.removeClass('on');
            }
        });
    },
    optionClick: function(e, $li){
        var val = $li.data('value');
        this.setData('value', val);
        this.trigger('change', val);
        e.stopPropagation();
    },
    tpl: function(){
        var midClass = this.option.mid ? 'dropbox-mid' : '',
            styleStr = this.option.width ? 'style="width:'+(this.option.width-35)+'px;"' : '';
        return '<div class="dropbox '+ midClass +'" '+ styleStr +'> \
                    <span class="droptext">{{if value!==undefined}} {{options[value]}} {{else}} {{emptyTitle}} {{/if}}  </span> \
                        <a class="btn-dropbox" href="#"><i class="i-sj"></i></a> \
                        <input type="hidden" name="{{name}}" id="{{name}}" value="{{value}}" /> \
                    <ul class="dropbox-list"> \
                        {{if (isEmptyObject(options) && emptyTip)}} \
                            <li><span class="empty-tip">{{emptyTip}}</span></li> \
                        {{else}} \
                            {{if options.all}} \
                                <li data-value="all"><a href="javascript:">{{options.all}}</a></li> \
                            {{/if}} \
                            {{each options as text key}} \
                            {{if key !=="all"}} \
                                <li data-value="{{key}}"><a href="javascript:">{{text}}</a></li> \
                            {{/if}} \
                            {{/each}} \
                        {{/if}} \
                    </ul> \
                </div>';
    },
    getValue: function(){
        return this.data.value;
    },
    getName: function(){
        var val = this.getValue();
        return val ? this.data.options[val] : '';
    }
});



/*
 * 多选下拉列表组件
 * data参数格式为：
    {
        name: 'domain_name',
        values: ['1'],
        noselectTitle: '请选择域名',    // 没选择时显示的title
        emptyTitle: '域名列表为空',     // options为空时列表显示的title
        maxLength: 8,                   // 最多选择条数
        options: {
            "all": "全部域名",          // 值为all时特殊，会触发全选动作
            "1": "sy.com",
            "2": "syy.com",
            "3": "test.com",
            "4": "tes1t.com"
        }
    }
 * option参数：
    {
        mid: true/false,    // 稍窄的宽度
        width: 120          // 指定具体宽度
    }
 */
xyForm.MutipleDropdownSelect = Component.extend({
    hooks: {
        dropbox: '.dropbox',
        valuebox: '.droptext'
    },
    events: {
        'li:click': 'optionClick',
        'li input:click': 'checkboxClick'
    },
    data: {
        name:"", 
        values:[],
        options: {}
    },
    //values: [],

    construct: function(data, option){
        var that = this;
        $(document).click(function(){
            that.$dropbox.removeClass('on');
            that.$maxTip && that.$maxTip.remove();
        });
        this.$root.click(function(e){
            if($(this).hasClass('component-disabled')) return;
            that.$dropbox.toggleClass('on');
            that.publish('hideDroplist', that);
            that.$maxTip && that.$maxTip.remove();
            e.preventDefault();
            e.stopPropagation();
        });
        this.values = this.data.values;
        if(this.values.length == 1 && this.values[0]=='all'){
            this.values = this.getAllValues();
        }
        this.updateValueTitle();
        this.initCheckbox();
        this.subscribe('hideDroplist', function(instance){
            if(instance !== that){
                that.$dropbox.removeClass('on');
            }
        });
    },

    setData: function(key, val){
        this._super(key, val);
        this.values = this.data.values;
        if(this.values.length == 1 && this.values[0]=='all'){
            this.values = this.getAllValues();
        }
        this.updateValueTitle();
        this.initCheckbox();
    },

    optionClick: function(e, $li){
        if($(e.target).is('a')){
            $li.find('input').click();
        }
        e.stopPropagation();
    },

    checkboxClick: function(e, $input){
        if($input.val() == 'all'){
            if($input.is(':checked')){
                this.$dropbox.find('input').each(function(){
                    this.checked = true;
                });
            }else{
                this.$dropbox.find('input').attr('checked', false);
            }
        }
        if(this.isOverMaxLength() === true){
            this.$maxTip && this.$maxTip.remove();
            this.$maxTip = xyTip.show({
                content: '最多可选择'+this.data.maxLength+'个',
                target: $input.closest('li')
            });
            e.preventDefault();
            return;
        }
        this.checkAllSelect();
        this.updateValue();
        this.updateValueTitle();
        e.stopPropagation();
    },

    isOverMaxLength: function(){
        if(this.data.maxLength && this.$root.find('input:checked').length > this.data.maxLength){
            return true;
        }
        return false;
    },

    getValues: function(){
        return this.values;
    },

    getAllValues: function(){
        var values = [];
        this.$root.find('input').each(function(){
            var val = $(this).val();
            if(val !== 'all'){
                values.push($(this).val());
            }
        });
        return values;
    },

    updateValue: function(){
        var values = [];
        this.$root.find('input:checked').each(function(){
            var val = $(this).val();
            if(val !== 'all'){
                values.push($(this).val());
            }
        });
        this.values = values;
        this.trigger('change', values);
    },

    updateValueTitle: function(){
        var items = [], valueStr, that = this;
        if(!this.data.options || $.isEmptyObject(this.data.options)){
            this.disable();
        }else{
            this.enable();
        }
        if(!this.data.options || $.isEmptyObject(this.data.options) && this.data.emptyTitle){
            // options为空时
            valueStr = this.data.emptyTitle;
            this.$valuebox.data('title', '');
        }else if(!this.values || this.values.length===0){
            // 没选择时
            valueStr = this.data.noselectTitle;
            this.$valuebox.data('title', '');
        }else if(this.isValuesEqual(this.values, this.getAllValues()) && this.data.options['all']){
            // 全选
            valueStr = this.data.options['all'];
            this.$valuebox.data('title', '');
        }else{
            $.each(this.values, function(k, v){
                items.push(that.data.options[v]);
            })
            valueStr = items.join(', ');
            this.$valuebox.data('title', valueStr);
        }
        this.$valuebox.html(valueStr);
    },

    checkAllSelect: function(){
        if(!this.data.options['all']) return;
        var selectedVal = [], 
            allInput = this.$dropbox.find('input[value="all"]')[0];
        this.$dropbox.find('input:checked').each(function(){
            var val = $(this).val();
            if(val !== 'all'){
                selectedVal.push(val);
            }
        });
        if(this.isValuesEqual(selectedVal, this.getAllValues())){
            allInput.checked = true;
        }else{
            allInput.checked = false;
        }
    },

    initCheckbox: function(){
        if(!this.values || this.values.length === 0) return;
        var that = this;
        $.each(this.values, function(k, v){
            that.$root.find('input[value="'+ v +'"]').attr('checked', true);
        });
        if(this.isValuesEqual(this.values, this.getAllValues())){
            that.$root.find('input[value="all"]').attr('checked', true);
        }
    },

    setWidth: function(width){
        this.$dropbox.css('width', width-35);
    },

    isValuesEqual: function(vals1, vals2){
        if(vals1.length !== vals2.length) return false;
        vals1.sort();
        vals2.sort();
        var isEqual = true;
        $.each(vals1, function(i, val){
            if(val != vals2[i]){
               isEqual = false; 
            }
        });
        return isEqual;
    },

    tpl: function(){
        var midClass = this.option.mid ? 'dropbox-mid' : '',
            styleStr = this.option.width ? 'style="width:'+(this.option.width-35)+'px;"' : '';
            
        return '<div class="dropbox '+ midClass +'" '+ styleStr +' > \
                    <span class="droptext '+ midClass +'"></span> \
                        <a class="btn-dropbox" href="#"><i class="i-sj"></i></a> \
                    <ul class="dropbox-list"> \
                        {{if options.all}} \
                            <li><a href="javascript:"><input type="checkbox" class="listcheck" value="all" /> {{options.all}}</a></li> \
                        {{/if}} \
                        {{each options as text key}} \
                            {{if key!=="all"}} \
                                <li><a href="javascript:"><input type="checkbox" class="listcheck" value="{{key}}" /> {{text}}</a></li> \
                            {{/if}} \
                        {{/each}} \
                    </ul> \
                </div>';
    },

    disable: function(){
        this.$root.addClass('component-disabled');
    },

    enable: function(){
        this.$root.removeClass('component-disabled');
    }
});

/*
 * 日期选择框
 * data参数格式：
 *  {
      date: '2015-07-07',
      max: '2015-08-31',
      min: '2015-06-01',
      name: 'begin_date',
      format: 'yyyy-MM-dd'
    }
 * 主动获取组件值：cmp.getValue();  
 */
xyForm.DatePicker = Component.extend({
    hooks: {'input': '.datetext'},
    val: null,
    construct: function(data, option){
        var param = {el:this.data.name};
        if(this.data.max) param.maxDate = this.data.max;
        if(this.data.min) param.minDate = this.data.min;
        if(this.data.format) param.dateFmt = this.data.format;
        this.$root.click(function(){
            WdatePicker(param);
        });
        this.val = this.getValue();
        this.simuateChangeEvent();
    },
    tpl: function(){
        return '<div class="datebox"> \
                    <input type="text" class="datetext" id="{{name}}" name="{{name}}" value="{{date}}" /> \
                    <a class="btn-datebox" href="javascript:;"><i class="i-date"></i></a> \
                </div>';
    },
    getValue: function(){
        return this.$input.val();
    },
    setValue: function(date){
        this.setData({date: date});
    },

    // 监控不到输入框的change事件，WdatePicker插件也没提供，只能自己模拟了
    simuateChangeEvent: function(){
        var that = this, currVal;
        window.setInterval(function(){
            currVal = that.getValue();
            if(currVal != that.val){
                that.val = currVal;
                that.trigger('change', currVal);
            }
        },200);
    }
});

/*
 * TabBtn组件
 * data参数格式：
    {
        list:{
            '1month': '近1月',
            '3month': '近3月',
            '6month': '近6月'
        },
        value: '1month'
    }
 * 点击改变时会触发change事件
 * 主动获取组件值：cmp.getValue();  
 */
xyForm.TabBtn = Component.extend({
    _val: null,
    events: {
        'a:click': 'clickHandler'        
    },
    construct: function(){
        if(this.data.value){
            this.$root.find('a[data-tag="'+ this.data.value +'"]').click();
        }else{
            this.$root.find('a:eq(0)').click();    
        }
    },
    clickHandler: function(e, $item){
        $item.addClass('on').siblings().removeClass('on');
        var val = $item.data('tag');
        if(val !== this._val){
            this._val = val;
            this.trigger('change', val);
        }
    },
    getValue: function(){
        return this._val;
    },
    tpl: function(){
        return '<div class="tabbtn clearfix"> \
                    {{each list as text val}} \
                        <a href="javascript:;" data-tag="{{val}}">{{text}}</a> \
                    {{/each}} \
                </div>';
    },
    clear: function(){
        this.$root.find('a').removeClass('on');
        this._val = null;
    }
});


/*
 * 对话框弹层
 * 参数： 
    {
        width: 640,
        height: 400,
        title: '设置',
        content: '...',      // 内容可以为：字符串、jQuery DOM对象、Component组件对象
        contentPadding: 40,
        mask: true
    }
 */
var xyDialog = Component.extend({
    data: {
        title: '',
        mask: true,
        width: 640
    },

    hooks: {
        box: '.pop-box',
        title: '.pop-title h3',
        content: '.pop-main'
    },

    events: {
        '.btn-close:click': 'close'
    },

    construct: function(data, option){
        this.fillContent();
        $('body').append(this.$root);
    },

    fillContent: function(){
        if(this.data.content instanceof Component){
            this.$content.html(this.data.content.getRoot());
        }else{
            this.$content.html(this.data.content);
        }
    },

    open: function(){
        var that = this;
        this.$box.show();
        window.setTimeout(function(){
            that.adjustPosition();
        }, 0);
        if(this.data.mask){
            this.showMask();
        }
        this.trigger('open');
        return this;
    },

    close: function(e){
        this.$box.hide();
        this.$mask && this.$mask.hide();
        this.trigger('close');
        e && e.preventDefault();
        return this;
    },

    destroy: function(){
        this.$root.remove();
        this.$mask && this.$mask.remove();
        this.trigger('destroy');
        return this;
    },

    showMask: function(){
        if(!this.$mask){
            this.$mask = $('<div class="popbg none"></div>').appendTo('body');
        }
        this.$mask.show();
    },

    adjustPosition: function(){
        var width = this.$box.width(),
            height = this.$box.height();
        this.$box.css({
            'margin-top': 0-height/2,
            'margin-left': 0-width/2
        });
    },

    tpl: function(){
        return '<div class="pop-box none" style=" {{if width}}width:{{width}}px;{{/if}} {{if height}}height:{{height}}px;{{/if}} "> \
                    <div class="pop-set"> \
                        {{if title}}<div class="pop-title"><h3>{{title}}</h3></div>{{/if}} \
                        <div class="pop-main" style="{{if typeof contentPadding!= \'undefined\'}}padding:{{contentPadding}}px;{{/if}}"></div> \
                        {{if title}} \
                            <a class="btn-pop-close btn-close" href="#">关闭</a> \
                        {{else}} \
                            <a class="btn-popclose btn-close" href="#">关闭</a> \
                        {{/if}} \
                    </div> \
                </div>';
    }
});

/*
 * Confirm对话框
 * 参数： 
    {
        width: 640,
        height: 400,
        btnText: '确定',
        content: '...', 
        callback: function(){}
    }
 */
var xyConfirm = Component.extend({
    data: {
        width: 325,
        btnText: '确定',
        content: '',
        mask: true
    },

    hooks: {
        box: '.pop-box'
    },

    events: {
        '.btn-normal:click': 'submit',
        '.btn-pop-close:click': 'close'
    },

    construct: function(data, option){
        $('body').append(this.$root);
    },

    submit: function(e, $btn){
        this.data.callback && this.data.callback();
        this.trigger('ok');
        this.close();
        e.preventDefault();
    },

    open: function(){
        this.$box.show();
        if(this.data.mask){
            this.showMask();
        }
        this.adjustPosition();
        this.trigger('open');
        return this;
    },

    close: function(e){
        this.$box.hide();
        this.$mask && this.$mask.hide();
        this.trigger('close');
        e && e.preventDefault();
        return this;
    },

    destroy: function(){
        this.$root.remove();
        this.$mask && this.$mask.remove();
        this.trigger('destroy');
        return this;
    },

    adjustPosition: function(){
        var width = this.$box.width(),
            height = this.$box.height();
        this.$box.css({
            'margin-top': 0-height/2,
            'margin-left': 0-width/2
        });
    },

    showMask: function(){
        if(!this.$mask){
            this.$mask = $('<div class="popbg none"></div>').appendTo('body');
        }
        this.$mask.show();
    },

    tpl: function(){
        return '<div class="pop-box none" style=" {{if width}}width:{{width}}px;{{/if}} {{if height}}height:{{height}}px;{{/if}} "> \
                    <div class="pop-text"> \
                        <p>{{#content}}</p> \
                        <div class="pop-text-btn"> \
                            <a class="btn-normal" href="#">{{btnText}}</a> \
                        </div> \
                        <a class="btn-pop-close" href="#">关闭</a> \
                    </div> \
                </div>';
    }
});


/*
 * Tip提示
 * initDom参数： 
    {   
        target: '.selector',
        width: '100'
    }
 * show参数： 
    {   
        target: '.selector',
        content: '...',
        width: '100'
    }
 */
var xyTip = {
    $tip: null,

    initDom: function(option){
        var that = this, overTimer, outTimer;
        function mouseoverFn(){
            var content = $(this).data('title');
            if(!content) return;
            var data = {
                target: $(this),
                content: content
            };
            if(option.width) data.width = option.width;
            window.clearTimeout(outTimer);
            overTimer = window.setTimeout(function(){
                that.show(data, false);
            }, 500);
        }
        function mouseoutFn(){
            window.clearTimeout(overTimer);
            outTimer = window.setTimeout(function(){
                that.removeTip();
            }, 300);
        }
        if(option.target instanceof $){
            option.target.on('mouseover', mouseoverFn);
            option.target.on('mouseout', mouseoutFn)
        }else{
            $('body').on('mouseover', option.target, mouseoverFn);
            $('body').on('mouseout', option.target, mouseoutFn);
        }
    },

    show: function(option, autoClose){
        this.removeTip();
        var data = {content: option.content},
            $target = option.target instanceof $ ? option.target : $(option.target);
        if(option.width){
            data.width = option.width;
        }
        var html = this.render(data);
        var $tip = $(html).appendTo('body');
        this.adjustPosition($tip, $target);
        if(autoClose !== false){
            window.setTimeout(function(){
               $tip.remove();
            }, 1500);
        }
        this.$tip = $tip;
        return $tip;
    },

    adjustPosition: function($tip, $target){
        var width = $tip.width(),
            height = $tip.height(),
            tarOffset = $target.offset(),
            tarWidth = $target.outerWidth();
        var x = tarOffset.left + tarWidth/2 - width/2;
        var y = tarOffset.top - height - 15;
        $tip.offset({top:y,left:x});
    },

    removeTip: function(){
        this.$tip && this.$tip.remove();
    },

    render: function(data){
        if(!this.tplCompiled){
            this.tplCompiled = template.compile(this.tpl());
        }
        return this.tplCompiled(data);
    },

    tpl: function(){
        return '<div class="pop-box-ab" {{if width}}style="max-width:{{width}}px;_width:{{width}}px;"{{/if}}> \
                    <div class="bubble"> \
                        <p>{{content}}</p><i class="bubble-sj"></i> \
                    </div> \
                </div>';
    }
};

/*
 * 发送post数据
 */
$.xyPost = function(url, data, success, fail, context){
    context = context || window;
    $.ajax({
        method: 'post',
        url: url,
        data: JSON.stringify(data),
        contentType: 'application/json'
    }).done(function(){
        success.apply(context, arguments);
    }).fail(function(){
        fail && fail.apply(context, arguments);
    });
};

/**
 * 弹层里提交内容组件的基类
 */
 var PopSettingBase = Component.extend({
    //需要在hooks里配置resultTip
    showResultTip: function(msg, isSuccess){
        if(!this.$resultTip) return;
        var that = this,
            className = isSuccess ? 'ok' : 'err',
            tipHtml = '<span class="'+ className +'">'+ msg +'！</span>';
        this.$resultTip.show().html(tipHtml);
        window.setTimeout(function(){
            that.$resultTip.fadeOut();
        }, 2000);
    },

    disableBtn: function($btn, text){
        $btn.data('origintext', $btn.text());
        $btn.addClass('btn-disabled');
        if(text) $btn.text(text);
    },

    enableBtn: function($btn){
        $btn.removeClass('btn-disabled');
        var originText = $btn.data('origintext');
        if(originText) $btn.text(originText);
    },

    isBtnDisabled: function($btn){
        return $btn.hasClass('btn-disabled');
    }
 });
